package com.ruicar.afs.cloud.manage.finance.corporate.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruicar.afs.cloud.basic.api.corporate.dto.CorporateTransferApprovedDTO;
import com.ruicar.afs.cloud.basic.api.corporate.dto.CorporateTransferApprovedDetailDTO;
import com.ruicar.afs.cloud.basic.api.corporate.dto.DealCorporateResultDto;
import com.ruicar.afs.cloud.basic.api.corporate.fegin.InterFaceGroupFeign;
import com.ruicar.afs.cloud.common.core.constant.CommonConstants;
import com.ruicar.afs.cloud.common.core.exception.AfsBaseException;
import com.ruicar.afs.cloud.common.core.security.util.SecurityUtils;
import com.ruicar.afs.cloud.common.core.util.IResponse;
import com.ruicar.afs.cloud.common.modules.contract.enums.*;
import com.ruicar.afs.cloud.common.util.EmptyUtils;
import com.ruicar.afs.cloud.components.datadicsync.DicHelper;
import com.ruicar.afs.cloud.components.datadicsync.dto.DicDataDto;
import com.ruicar.afs.cloud.manage.common.entity.ManageApplyRecord;
import com.ruicar.afs.cloud.manage.common.entity.ManageApprovalRecord;
import com.ruicar.afs.cloud.manage.common.service.ManageApplyRecordService;
import com.ruicar.afs.cloud.manage.common.service.ManageApprovalRecordService;
import com.ruicar.afs.cloud.manage.finance.bankarrive.entity.ManageAccountRegister;
import com.ruicar.afs.cloud.manage.finance.bankarrive.entity.ManageBankAccount;
import com.ruicar.afs.cloud.manage.finance.bankarrive.service.ManageAccountRegisterService;
import com.ruicar.afs.cloud.manage.finance.bankarrive.service.ManageBankAccountService;
import com.ruicar.afs.cloud.manage.finance.corporate.condition.CaseOperateCondition;
import com.ruicar.afs.cloud.manage.finance.corporate.entity.ManageCorporateTransfer;
import com.ruicar.afs.cloud.manage.finance.corporate.mapper.ManageCorporateTransferMapper;
import com.ruicar.afs.cloud.manage.finance.corporate.service.ManageCorporateTransferService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Lee
 * @date 2020-05-30 04:45:15 
 * @description 
 */
@Service
@AllArgsConstructor
@Slf4j
public class ManageCorporateTransferServiceImpl extends ServiceImpl<ManageCorporateTransferMapper, ManageCorporateTransfer> implements ManageCorporateTransferService {

    private final ManageAccountRegisterService manageAccountRegisterService;

    private final ManageApprovalRecordService manageApprovalRecordService;

    private final InterFaceGroupFeign interFaceGroupFeign;

    private final ManageApplyRecordService manageApplyRecordService;

    private final ManageBankAccountService manageBankAccountService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void agreeSubmit(CaseOperateCondition caseOperateCondition,ManageCorporateTransfer corporateTransfer) {
        this.update(Wrappers.<ManageCorporateTransfer>lambdaUpdate()
                .eq(ManageCorporateTransfer::getId,corporateTransfer.getId())
                .eq(ManageCorporateTransfer::getCaseStatus, CaseStatusEnum.UNDER_REVIEW)
                .set(ManageCorporateTransfer::getCaseStatus,CaseStatusEnum.APPROVED)
                .set(ManageCorporateTransfer::getEndTime, Calendar.getInstance().getTime())
                .set(ManageCorporateTransfer::getDebitOrderStatus, caseOperateCondition.getDebitOrderStatus())
        );
        /**  审批记录信息新增 by ZC.GUO  **/
        ManageApprovalRecord approvalRecord = new ManageApprovalRecord();
        approvalRecord.setContractNo(corporateTransfer.getContractNo());
        approvalRecord.setCaseNo(corporateTransfer.getCaseNo());
        approvalRecord.setContractBusiness(CaseTypeEnum.BEFORE_CHARGE.equals(corporateTransfer.getCaseType())?ContractBusinessEnum.corporateSettlementPrepayment:ContractBusinessEnum.corporateSettlementRent);
        approvalRecord.setProcessPerson(SecurityUtils.getUser().getUserRealName());
        approvalRecord.setDepartment(SecurityUtils.getUser().getDeptId().toString());
        approvalRecord.setBizDataId(String.valueOf(corporateTransfer.getId()));

        approvalRecord.setProcessNode(null);
        approvalRecord.setNodeName("对公结算审核");
        approvalRecord.setApprovalOpinion(EmptyUtils.isNotEmpty(caseOperateCondition.getApprovalOpinion())?caseOperateCondition.getApprovalOpinion():"通过");
        approvalRecord.setRemarks(caseOperateCondition.getApprovalOpinion());
        manageApprovalRecordService.save(approvalRecord);
        /**  保存变更操作记录数据 by ZC.GUO  **/
        ManageApplyRecord applyRecord = manageApplyRecordService.getOne(Wrappers.<ManageApplyRecord>lambdaQuery()
                .eq(ManageApplyRecord::getCaseNo, corporateTransfer.getCaseNo()));
        if (EmptyUtils.isNotEmpty(applyRecord)){
            applyRecord.setCaseStatus(CaseStatusEnum.APPROVED);
            applyRecord.setEndDate(Calendar.getInstance().getTime());
            manageApplyRecordService.updateById(applyRecord);
        }else{
            ManageApplyRecord record = new ManageApplyRecord();
            record.setContractNo(corporateTransfer.getContractNo());
            record.setCaseNo(corporateTransfer.getCaseNo());
            record.setContractBusiness(CaseTypeEnum.BEFORE_CHARGE.equals(corporateTransfer.getCaseType())?ContractBusinessEnum.corporateSettlementPrepayment:ContractBusinessEnum.corporateSettlementRent);
            record.setCaseStatus(CaseStatusEnum.APPROVED);
            record.setDataSource(corporateTransfer.getDataSource());
            record.setBusinessSource(corporateTransfer.getCaseSource());
            record.setEndDate(Calendar.getInstance().getTime());
            manageApplyRecordService.save(record);
        }

        /**  银行到账信息更新 by ZC.GUO  **/
        List<AccountRegistStatusEnum> statusEnumList = new ArrayList<>();
        statusEnumList.add(AccountRegistStatusEnum.ALREADY_GENERA);
        statusEnumList.add(AccountRegistStatusEnum.WRITE_BACK);
        List<Long> idList = Arrays.stream(caseOperateCondition.getIds().split(",")).map(s ->Long.parseLong(s.trim())).collect(Collectors.toList());
        List<ManageAccountRegister> manageAccountRegisterList = manageAccountRegisterService.list(Wrappers.<ManageAccountRegister>query().lambda()
                .in(ManageAccountRegister::getId,idList)
                .in(ManageAccountRegister::getStatus,statusEnumList)
        );
        if (EmptyUtils.isNotEmpty(manageAccountRegisterList)){

            List<CorporateTransferApprovedDetailDTO> detailDTOList = new ArrayList<>();

            BigDecimal totalAmt = BigDecimal.ZERO;

            for (ManageAccountRegister manageAccountRegister:manageAccountRegisterList){
                manageAccountRegisterService.update(Wrappers.<ManageAccountRegister>lambdaUpdate()
                        .eq(ManageAccountRegister::getId,manageAccountRegister.getId())
                        .eq(ManageAccountRegister::getStatus,manageAccountRegister.getStatus())
                        .set(ManageAccountRegister::getStatus,AccountRegistStatusEnum.ALREADY_GOUJI)
                        .set(ManageAccountRegister::getCaseId,corporateTransfer.getId())
                        .set(ManageAccountRegister::getContractNo,corporateTransfer.getContractNo())
                );

                CorporateTransferApprovedDetailDTO detail = new CorporateTransferApprovedDetailDTO();
                detail.setSourceTable(ManageAccountRegister.class.getAnnotation(TableName.class).value());
                detail.setSourceId(manageAccountRegister.getId());
                detail.setArriveAmt(manageAccountRegister.getReceivedAmt());
                detail.setSourceAccountName(manageAccountRegister.getPaymentCust());
                detail.setSourceAccount(manageAccountRegister.getCustAccount());
                detail.setCreditAccount(manageAccountRegister.getBankAccount());

                ManageBankAccount bankAccount = manageBankAccountService.getOne(Wrappers.<ManageBankAccount>query().lambda()
                        .eq(ManageBankAccount::getAccount, manageAccountRegister.getBankAccount())
                        .eq(ManageBankAccount::getStatus, ValidOrInvalidEnum.valid)
                );
                if (EmptyUtils.isNotEmpty(bankAccount)){
                    detail.setCreditOpeningBankName(bankAccount.getBranchBankName());

                    Map<String, List<DicDataDto>> dicMap = DicHelper.getDicMaps("bankCode");
                    List<DicDataDto> dicList = dicMap.get("bankCode");
                    for (DicDataDto dicDataDto : dicList) {
                        if (dicDataDto.getValue().equals(bankAccount.getBankCode())) {
                            detail.setCreditBankName(dicDataDto.getTitle());
                        }
                    }
                }else{
                    throw new AfsBaseException("到账编号为："+manageAccountRegister.getEbankNo()+"的账号"+manageAccountRegister.getBankAccount()+"已失效,请检查");
                }


                detail.setContractNo(corporateTransfer.getContractNo());
                detailDTOList.add(detail);
                totalAmt = totalAmt.add(manageAccountRegister.getReceivedAmt());
            }
            /**  收据处理 by ZC.GUO  **/


            CorporateTransferApprovedDTO corporateTransferApprovedDTO = new CorporateTransferApprovedDTO();
            corporateTransferApprovedDTO.setOperator(SecurityUtils.getUser().getUsername());
            corporateTransferApprovedDTO.setDetailDTOList(detailDTOList);
            corporateTransferApprovedDTO.setContractNo(corporateTransfer.getContractNo());
            corporateTransferApprovedDTO.setApplyNo("");
            corporateTransferApprovedDTO.setTotalAmt(totalAmt);
            corporateTransferApprovedDTO.setRequestId(corporateTransfer.getId());
            corporateTransferApprovedDTO.setCaseType(corporateTransfer.getCaseType());

            IResponse<DealCorporateResultDto> response = null;
            if (CaseTypeEnum.BEFORE_CHARGE.equals(corporateTransferApprovedDTO.getCaseType())){
                response = interFaceGroupFeign.corporateTransferApprovedBeforeCharge(corporateTransferApprovedDTO);
            }else{
                response = interFaceGroupFeign.corporateTransferApprovedNormal(corporateTransferApprovedDTO);
            }
            if (EmptyUtils.isNotEmpty(response)&& CommonConstants.SUCCESS.equals(response.getCode())){
                DealCorporateResultDto  dealCorporateResultDto = response.getData();
                if (EmptyUtils.isNotEmpty(dealCorporateResultDto)&&!"0000".equals(dealCorporateResultDto.getDealResult())){
                    throw new AfsBaseException("对公结算收据处理失败");
                }
                log.info("对公结算收据处理成功");
            }else{
                throw new AfsBaseException("对公结算收据处理失败");
            }
        }
    }

    @Override
    public void refuseSubmit(CaseOperateCondition caseOperateCondition, ManageCorporateTransfer corporateTransfer) {
        this.update(Wrappers.<ManageCorporateTransfer>lambdaUpdate()
                .eq(ManageCorporateTransfer::getId,corporateTransfer.getId())
                .eq(ManageCorporateTransfer::getCaseStatus,CaseStatusEnum.UNDER_REVIEW)
                .set(ManageCorporateTransfer::getCaseStatus,CaseStatusEnum.REFUSE)
                .set(ManageCorporateTransfer::getEndTime,Calendar.getInstance().getTime())
                .set(ManageCorporateTransfer::getDebitOrderStatus, caseOperateCondition.getDebitOrderStatus())
        );
        /**  审批记录信息新增 by ZC.GUO  **/
        ManageApprovalRecord approvalRecord = new ManageApprovalRecord();
        approvalRecord.setContractNo(corporateTransfer.getContractNo());
        approvalRecord.setCaseNo(corporateTransfer.getCaseNo());
        approvalRecord.setContractBusiness(CaseTypeEnum.BEFORE_CHARGE.equals(corporateTransfer.getCaseType())?ContractBusinessEnum.corporateSettlementPrepayment:ContractBusinessEnum.corporateSettlementRent);
        approvalRecord.setProcessPerson(SecurityUtils.getUser().getUserRealName());
        approvalRecord.setDepartment(SecurityUtils.getUser().getDeptId().toString());
        approvalRecord.setBizDataId(String.valueOf(corporateTransfer.getId()));

        approvalRecord.setProcessNode(null);
        approvalRecord.setNodeName("对公结算审核");
        approvalRecord.setApprovalOpinion(caseOperateCondition.getApprovalOpinion());
        approvalRecord.setRemarks(caseOperateCondition.getApprovalOpinion());
        manageApprovalRecordService.save(approvalRecord);

        /**  保存变更操作记录数据 by ZC.GUO  **/
        ManageApplyRecord applyRecord = manageApplyRecordService.getOne(Wrappers.<ManageApplyRecord>lambdaQuery()
                .eq(ManageApplyRecord::getCaseNo, corporateTransfer.getCaseNo()));
        if (EmptyUtils.isNotEmpty(applyRecord)){
            applyRecord.setCaseStatus(CaseStatusEnum.REFUSE);
            applyRecord.setEndDate(Calendar.getInstance().getTime());
            manageApplyRecordService.updateById(applyRecord);
        }else{
            ManageApplyRecord record = new ManageApplyRecord();
            record.setContractNo(corporateTransfer.getContractNo());
            record.setCaseNo(corporateTransfer.getCaseNo());
            record.setContractBusiness(CaseTypeEnum.BEFORE_CHARGE.equals(corporateTransfer.getCaseType())?ContractBusinessEnum.corporateSettlementPrepayment:ContractBusinessEnum.corporateSettlementRent);
            record.setCaseStatus(CaseStatusEnum.REFUSE);
            record.setDataSource(corporateTransfer.getDataSource());
            record.setBusinessSource(corporateTransfer.getCaseSource());
            record.setApplyTime(DateUtil.date());
            record.setEndDate(Calendar.getInstance().getTime());
            manageApplyRecordService.save(record);
        }
    }

    @Override
    public boolean lockOrUnlockCorporateTransfer(ManageCorporateTransfer corporateTransfer) {

        int count = baseMapper
                .updateWhenOperateCorporateTrans(corporateTransfer.getIsOperating(),corporateTransfer.getId());
        if(count == 0) {
            log.info("乐观锁生效，对公结算记录更新失败，id:[{}]", new Object[]{corporateTransfer.getId()});
            return false;
        }else{
            return true;
        }
    }
}
